package com.ard.camera.demos.controller;

import com.ard.camera.demos.DvrHostFileReader;
import com.ard.camera.demos.DvrHostPingChecker;
import com.ard.camera.demos.entry.DvrHostEntry;
import com.ard.camera.demos.service.DvrEmailService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@RestController
@RequestMapping("/api/dvr-monitor")
public class DvrMonitorController {

    private static final Logger log = LoggerFactory.getLogger(DvrMonitorController.class);

    @Autowired
    private DvrHostPingChecker dvrHostPingChecker;

    @Autowired
    private DvrEmailService dvrEmailService;

    @Autowired
    private DvrHostFileReader dvrHostFileReader;

    /**
     * 手动触发所有硬盘录像机检查
     */
    @GetMapping("/check-all")
    public ResponseEntity<Map<String, Object>> manualCheckAll() {
        try {
            Map<String, List<DvrHostPingChecker.DvrHostCheckResult>> allResults =
                    dvrHostPingChecker.checkAllDvrHosts();

            // 提取失败的主机
            Map<String, List<DvrHostPingChecker.DvrHostCheckResult>> failedDvrHosts = new HashMap<>();
            int totalFailed = 0;

            for (Map.Entry<String, List<DvrHostPingChecker.DvrHostCheckResult>> entry : allResults.entrySet()) {
                String dvrIp = entry.getKey();
                List<DvrHostPingChecker.DvrHostCheckResult> results = entry.getValue();

                // 使用传统方式过滤失败的主机
                List<DvrHostPingChecker.DvrHostCheckResult> failedHosts = new ArrayList<>();
                for (DvrHostPingChecker.DvrHostCheckResult result : results) {
                    if (!result.isReachable()) {
                        failedHosts.add(result);
                    }
                }

                if (!failedHosts.isEmpty()) {
                    failedDvrHosts.put(dvrIp, failedHosts);
                    totalFailed += failedHosts.size();
                }
            }

            if (!failedDvrHosts.isEmpty()) {
                dvrEmailService.sendDvrHostAlert(failedDvrHosts);
            }

            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("totalDvrs", allResults.size());
            response.put("failedDvrs", failedDvrHosts.size());
            response.put("totalFailedHosts", totalFailed);
            response.put("results", formatResults(allResults));

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("手动检查硬盘录像机失败", e);
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("success", false);
            errorResponse.put("error", e.getMessage());
            return ResponseEntity.status(500).body(errorResponse);
        }
    }

    /**
     * 检查单个硬盘录像机
     */
    @GetMapping("/check-dvr/{dvrIp}")
    public ResponseEntity<Map<String, Object>> checkSingleDvr(@PathVariable String dvrIp) {
        try {
            List<DvrHostPingChecker.DvrHostCheckResult> results =
                    dvrHostPingChecker.checkDvrHosts(dvrIp);

            // 使用传统方式过滤失败的主机
            List<DvrHostPingChecker.DvrHostCheckResult> failedHosts = new ArrayList<>();
            for (DvrHostPingChecker.DvrHostCheckResult result : results) {
                if (!result.isReachable()) {
                    failedHosts.add(result);
                }
            }

            if (!failedHosts.isEmpty()) {
                Map<String, List<DvrHostPingChecker.DvrHostCheckResult>> failedMap = new HashMap<>();
                failedMap.put(dvrIp, failedHosts);
                dvrEmailService.sendDvrHostAlert(failedMap);
            }

            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("dvrIp", dvrIp);
            response.put("totalHosts", results.size());
            response.put("failedHosts", failedHosts.size());
            response.put("results", formatDvrResults(results));

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("检查单个硬盘录像机失败: {}", dvrIp, e);
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("success", false);
            errorResponse.put("dvrIp", dvrIp);
            errorResponse.put("error", e.getMessage());
            return ResponseEntity.status(500).body(errorResponse);
        }
    }

    /**
     * 获取所有硬盘录像机的检查状态
     */
    @GetMapping("/status")
    public ResponseEntity<Map<String, Object>> getStatus() {
        try {
            Map<String, List<DvrHostPingChecker.DvrHostCheckResult>> allResults =
                    dvrHostPingChecker.checkAllDvrHosts();

            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("totalDvrs", allResults.size());
            response.put("results", formatResults(allResults));

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("获取状态失败", e);
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("success", false);
            errorResponse.put("error", e.getMessage());
            return ResponseEntity.status(500).body(errorResponse);
        }
    }

    /**
     * 重新加载硬盘录像机配置
     */
    @GetMapping("/reload")
    public ResponseEntity<Map<String, Object>> reloadDvrConfigs() {
        try {
            Map<String, List<DvrHostEntry>> allDvrHosts = dvrHostFileReader.reloadAllDvrHosts();

            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("message", "硬盘录像机配置重新加载成功");
            response.put("totalDvrs", allDvrHosts.size());
            response.put("dvrIps", new ArrayList<>(allDvrHosts.keySet()));
            response.put("dvrHosts", formatDvrHosts(allDvrHosts));

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("重新加载硬盘录像机配置失败", e);
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("success", false);
            errorResponse.put("error", e.getMessage());
            return ResponseEntity.status(500).body(errorResponse);
        }
    }

    /**
     * 获取所有硬盘录像机列表
     */
    @GetMapping("/dvrs")
    public ResponseEntity<List<Map<String, Object>>> getDvrList() {
        Map<String, List<DvrHostEntry>> allDvrHosts = dvrHostPingChecker.getAllDvrHosts();

        List<Map<String, Object>> dvrList = new ArrayList<>();

        for (Map.Entry<String, List<DvrHostEntry>> entry : allDvrHosts.entrySet()) {
            Map<String, Object> dvrInfo = new HashMap<>();
            dvrInfo.put("dvrIp", entry.getKey());
            dvrInfo.put("hostCount", entry.getValue().size());

            // 处理主机列表
            List<Map<String, String>> hosts = new ArrayList<>();
            for (DvrHostEntry he : entry.getValue()) {
                Map<String, String> hostInfo = new HashMap<>();
                hostInfo.put("address", he.getHostAddress());
                hostInfo.put("name", he.getHostName());
                hosts.add(hostInfo);
            }
            dvrInfo.put("hosts", hosts);

            dvrList.add(dvrInfo);
        }

        return ResponseEntity.ok(dvrList);
    }

    /**
     * 格式化结果数据
     */
    private Map<String, Object> formatResults(
            Map<String, List<DvrHostPingChecker.DvrHostCheckResult>> allResults) {

        Map<String, Object> formatted = new HashMap<>();

        for (Map.Entry<String, List<DvrHostPingChecker.DvrHostCheckResult>> entry : allResults.entrySet()) {
            String dvrIp = entry.getKey();
            List<Map<String, Object>> hostResults = new ArrayList<>();

            for (DvrHostPingChecker.DvrHostCheckResult r : entry.getValue()) {
                Map<String, Object> resultMap = new HashMap<>();
                resultMap.put("hostAddress", r.getDvrHostEntry().getHostAddress());
                resultMap.put("hostName", r.getDvrHostEntry().getHostName());
                resultMap.put("reachable", r.isReachable());
                resultMap.put("attempts", r.getAttempts());
                resultMap.put("errorMessage", r.getErrorMessage());
                hostResults.add(resultMap);
            }

            formatted.put(dvrIp, hostResults);
        }

        return formatted;
    }

    /**
     * 格式化单个硬盘录像机结果
     */
    private List<Map<String, Object>> formatDvrResults(
            List<DvrHostPingChecker.DvrHostCheckResult> results) {

        List<Map<String, Object>> formattedResults = new ArrayList<>();

        for (DvrHostPingChecker.DvrHostCheckResult r : results) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("hostAddress", r.getDvrHostEntry().getHostAddress());
            resultMap.put("hostName", r.getDvrHostEntry().getHostName());
            resultMap.put("reachable", r.isReachable());
            resultMap.put("attempts", r.getAttempts());
            resultMap.put("errorMessage", r.getErrorMessage());
            formattedResults.add(resultMap);
        }

        return formattedResults;
    }

    /**
     * 格式化硬盘录像机主机配置
     */
    private Map<String, Object> formatDvrHosts(Map<String, List<DvrHostEntry>> allDvrHosts) {
        Map<String, Object> formatted = new HashMap<>();

        for (Map.Entry<String, List<DvrHostEntry>> entry : allDvrHosts.entrySet()) {
            String dvrIp = entry.getKey();
            List<Map<String, String>> hosts = new ArrayList<>();

            for (DvrHostEntry he : entry.getValue()) {
                Map<String, String> hostInfo = new HashMap<>();
                hostInfo.put("address", he.getHostAddress());
                hostInfo.put("name", he.getHostName());
                hosts.add(hostInfo);
            }

            formatted.put(dvrIp, hosts);
        }

        return formatted;
    }

    /**
     * 测试单个主机连通性
     */
    @GetMapping("/test-ping")
    public ResponseEntity<Map<String, Object>> testPing(@RequestBody Map<String, String> request) {
        try {
            String host = request.get("host");
            int timeout = request.containsKey("timeout") ?
                    Integer.parseInt(request.get("timeout")) : 5000;

            boolean reachable = dvrHostPingChecker.isHostReachable(host, timeout);

            Map<String, Object> response = new HashMap<>();
            response.put("success", true);
            response.put("host", host);
            response.put("reachable", reachable);
            response.put("timeout", timeout);

            return ResponseEntity.ok(response);

        } catch (Exception e) {
            log.error("测试Ping失败", e);
            Map<String, Object> errorResponse = new HashMap<>();
            errorResponse.put("success", false);
            errorResponse.put("error", e.getMessage());
            return ResponseEntity.status(500).body(errorResponse);
        }
    }


}